/**
 * 模式 保护性暂停 同步
 * @author 管子
 * @date 2025/4/23 20:43
 * @description: GuardedObject 类
 */
public class GuardedObject {

    // 结果
    private Object response;

    // 获取结果
    public Object get() {
        synchronized (this) {
            // 套路，while条件不成立时，持续wait，否则继续往下执行
            while (response == null) {
                try {
                    // 调用get方法的线程阻塞等待，类似thread.join()，future.get()方法
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return response;
        }
    }

    // 最多等待多久获取结果
    public Object get(long timeout) {
        synchronized (this) {
            // 记录一个开始时间，什么时刻开始等待
            long begin = System.currentTimeMillis();
            // 经历了多长时间
            long passedTime = 0;
            while (response == null && passedTime <= timeout) {
                // 假设开始秒是00，timeout是2s，如果在01被虚假唤醒，则不应该还等timeout=2s，应该还在等1s，满足timeout总时长就退出
                // 所以这里的wait时间，应该是timeout-passedTime!! 为了保证整个方法等待的总时长不超过timeout
                long waitTime = timeout - passedTime;
                try {
                    this.wait(waitTime);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 求得经历时间
                passedTime = System.currentTimeMillis() - begin;
            }
            return response;
        }
    }

    // 产生结果
    public void complete(Object result) {
        synchronized (this) {
            // 给成员变量赋值
            this.response = result;
            // 给自己这个对象的锁做唤醒操作
            this.notifyAll();
        }
    }

}
